/*
*   事件管理器，事件的监听、触发、移除
*/
export type EventManagerCallFunc = (...args) => void;

interface CallBackData {
    callBack: EventManagerCallFunc,
    target: any,
}

class EventManager {
    private static instance: EventManager = null;
    public static getInstance(): EventManager {
        if (!this.instance) {
            this.instance = new EventManager();
        }
        return this.instance;
    }

    public static destroy(): void {
        if (this.instance) {
            this.instance = null;
        }
    }

    private _eventListeners: Map<string, CallBackData[]> = new Map<string, CallBackData[]>();

    private getEventListenersIndex(eventName: string, callBack: EventManagerCallFunc, target?: any): number {
        let index = -1;
        for (let i = 0; i < this._eventListeners.get(eventName).length; i++) {
            let iterator = this._eventListeners.get(eventName)[i];
            if (iterator.callBack == callBack && (!target || iterator.target == target)) {
                index = i;
                break;
            }
        }
        return index;
    }

    addEventListener(eventName: string, callBack: EventManagerCallFunc, target?: any): boolean {
        if (!eventName) {
            return;
        }

        if (null == callBack) {
            return false;
        }
        let callTarget: CallBackData = { callBack: callBack, target: target };

        if (this._eventListeners.has(eventName) == false) {
            this._eventListeners.set(eventName, [callTarget]);
        } else {
            let index = this.getEventListenersIndex(eventName, callBack, target);
            if (-1 == index) {
                this._eventListeners.get(eventName).push(callTarget);
            }
        }

        return true;
    }

    removeEventListener(eventName: string, callBack: EventManagerCallFunc, target?: any) {

        if (null != this._eventListeners.has(eventName)) {

            let index = this.getEventListenersIndex(eventName, callBack, target);

            if (-1 != index) {
                this._eventListeners.get(eventName).splice(index, 1);
            }
        }
    }

    dispatchEvent(eventName: string, ...args) {
        if (this._eventListeners.has(eventName)) {
            // 将所有回调提取出来，再调用，避免调用回调的时候操作了事件的删除
            let callbackList: CallBackData[] = [];
            for (const iterator of this._eventListeners.get(eventName)) {
                callbackList.push({ callBack: iterator.callBack, target: iterator.target });
            }
            for (const iterator of callbackList) {
                iterator.callBack.call(iterator.target, ...args);
            }
        }
    }
}

export let eventMgr = EventManager.getInstance();